<?php


namespace app\command\count;


use app\common\model\CountDuty;
use app\common\model\MemberDutyModel;
use org\DingDingRobot;
use think\console\Command;
use think\console\Output;
use think\console\Input;
use think\console\input\Argument;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 签到统计
 * Class DutyCommand
 * @package app\command\count
 */
class CountDutyCommand extends Command
{
    protected function configure()
    {
        $this->setName('count_duty')
            ->addArgument('begin_day', Argument::OPTIONAL, '指定执行开始日期')
            ->addArgument('end_day', Argument::OPTIONAL, '指定执行截至日期')
            ->setDescription('签到统计');
    }

    /**
     * @param Input $input
     * @param Output $output
     * @return int|void|null
     */
    protected function execute(Input $input, Output $output)
    {
        $begin_day = $input->getArgument('begin_day');
        $end_day   = $input->getArgument('end_day');

        if (empty($end_day) && empty($begin_day)) {

            # 定时任务配置在凌晨之后，默认跑前一天的数据
            $date = date('Y-m-d', strtotime(date('Y-m-d') . ' -1 day'));
            $this->buildData($date,$output);

        } elseif (!empty($begin_day) && !empty($end_day)) {

            # 跑指定日期范围的数据
            $begin_time = strtotime(date('Y-m-d 00:00:00', strtotime($begin_day)));
            $end_time   = strtotime(date('Y-m-d 23:59:59', strtotime($end_day)));

            for ($i = $begin_time; $i < $end_time; $i += 86400) {
                $date = date('Y-m-d', $i);
                $this->buildData($date,$output);
                $output->info($date);
            }

        } elseif (!empty($begin_day)) {
            # 跑指定日期的数据
            $date = date('Y-m-d', strtotime($begin_day));
            $this->buildData($date,$output);
            $output->info($date);
        }

    }

    /**
     * 执行
     * 签到人数    金币总数    首次签到    第1天    第2天    第3天    第4天    第5天    第6天    第7天    8-30天    30天以上
     * ● 首次签到：判断用户从未有到记录
     * ● 第1天：这种情况出现在用户断签后连续签的第1天
     * @param string $date
     * @param Output $output
     */
    protected function buildData(string $date,Output $output)
    {

        try {
            $field = [
                "count(DISTINCT member_id) user_num", # 签到人数
                "sum(amount) gold_num", # 奖励金额 - 金币总数
                "sum(if(day=1,1,0)) day_1", # 第1天
                "sum(if(day=2,1,0)) day_2", # 第2天
                "sum(if(day=3,1,0)) day_3", # 第3天
                "sum(if(day=4,1,0)) day_4", # 第4天
                "sum(if(day=5,1,0)) day_5", # 第5天
                "sum(if(day=6,1,0)) day_6", # 第6天
                "sum(if(day=7,1,0)) day_7", # 第7天
                "sum(if(day > 7 and day < 31,1,0)) day_8_30", # 8-30天
                "sum(if(day > 30,1,0)) day_30", # 30天以上
            ];

            $data = MemberDutyModel::where("write_date", $date)->field($field)->find()->toArray();

            // 第一天签到的用户，可能不是首次签到,
            $member_new = MemberDutyModel::where("write_date",$date)->where('day',1)->column("member_id");
            # 之前签到过的用户
            $member_old = (new \app\common\model\MemberDutyModel)
                ->where([
                    ['member_id','IN',$member_new],
                    ['write_date','<',$date],
                ])->group("member_id")->column("member_id");

            # 首次签到用户数
            $data['first_sign_in'] = count(array_diff($member_new,$member_old));  // 取差集得到首次签到的用户
            $data['create_time'] = time();
            $data['record_date'] = $date;

            $row = CountDuty::where("record_date",$date)->find();

            if($row){
                CountDuty::where('id',$row['id'])->save(array_filter($data));
            }else{
                (new \app\common\model\CountDuty)->insert(array_filter($data));
            }

            DingDingRobot::getInstance()->pushText("签到统计,执行完成，日期:{$date}");
        } catch (DataNotFoundException $e) {
            DingDingRobot::getInstance()->pushText("签到统计异常，日期:{$date},内容：" . $e->getMessage());
        } catch (ModelNotFoundException $e) {
            DingDingRobot::getInstance()->pushText("签到统计异常，日期:{$date},内容：" . $e->getMessage());
        } catch (DbException $e) {
            DingDingRobot::getInstance()->pushText("签到统计异常，日期:{$date},内容：" . $e->getMessage());
        }

    }
}